package com.xyh.transaction.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.StringUtils;
import com.xyh.transaction.common.Current;
import com.xyh.transaction.common.GoodsCondition;
import com.xyh.transaction.entity.Category;
import com.xyh.transaction.entity.Goods;
import com.xyh.transaction.exception.BusinessException;
import com.xyh.transaction.mapper.CategoryMapper;
import com.xyh.transaction.mapper.GoodsMapper;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;

@Slf4j
public class ImportGoodsVoListener implements ReadListener<ExcelGoodsVo> {

    private final Boolean isCover;
    private final GoodsMapper goodsMapper;
    private final CategoryMapper categoryMapper;

    private Integer rowIndex = 0;

    public ImportGoodsVoListener(Boolean isCover, GoodsMapper goodsMapper, CategoryMapper categoryMapper) {
        this.isCover = isCover;
        this.goodsMapper = goodsMapper;
        this.categoryMapper = categoryMapper;
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        ReadListener.super.onException(exception, context);
    }

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        ReadListener.super.invokeHead(headMap, context);
    }

    @Override
    public void invoke(ExcelGoodsVo data, AnalysisContext context) {
        log.info("开始读取商品列表数据！");
        rowIndex++;
        Integer userId = Current.getCurrentUser().getUser().getId();
        String categoryName = data.getCategoryName();
        Integer stock = data.getStock();
        BigDecimal price = data.getPrice();
        String des = data.getDes();
        String condition = data.getCondition();
        String name = data.getName();
        String code = data.getCode();

        verifyField(data);
        Category category = categoryMapper.findByName(categoryName);
        if (category == null) {
            throw new BusinessException("在第" + rowIndex + "行发现错误，商品类别不符合要求！");
        }
        if (stock < 0) {
            throw new BusinessException("在第" + rowIndex + "行发现错误，库存不能为负数！");
        }
        // 校验价格不能为负数
        if (price.compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException("在第" + rowIndex + "行发现错误：价格不能为负数");
        }
        // 校验价格精度，确保小数点后最多两位
        if (price.scale() > 2) {
            throw new BusinessException("在第" + rowIndex + "行发现错误：价格精度超过两位小数");
        }

        Goods goods = new Goods();
        goods.setStock(stock);
        goods.setName(name);
        goods.setCategoryId(category.getId());
        goods.setUpdateBy(userId);
        goods.setUpdateTime(LocalDateTime.now());
        goods.setDesc(des);
        goods.setCondition(GoodsCondition.getByDetail(condition));
        goods.setPrice(price);

        Goods oldGoods = goodsMapper.findByCode(code);
        goods.setCode(code);
        if (isCover) {
            if (oldGoods == null) {
                throw new BusinessException("在第" + rowIndex + "行发现错误：系统不存在该商品编码【" + code + "】商品数据");
            }
            goods.setId(oldGoods.getId());
            goodsMapper.update(goods);
        } else {
            if (oldGoods != null) {
                throw new BusinessException("在第" + rowIndex + "行发现错误：系统已存在该商品编码【" + code + "】商品数据");
            }
            goods.setCreateBy(userId);
            goods.setCreateTime(LocalDateTime.now());
            goodsMapper.insert(goods);
        }
    }

    public void verifyField(ExcelGoodsVo data) throws BusinessException {
        if (StringUtils.isBlank(data.getCode())) {
            throw new BusinessException("在第" + rowIndex + "行发现错误：商品编码不能为空");
        }
        if (StringUtils.isBlank(data.getCategoryName())) {
            throw new BusinessException("在第" + rowIndex + "行发现错误：类别名不能为空");
        }
        if (StringUtils.isBlank(data.getCondition())) {
            throw new BusinessException("在第" + rowIndex + "行发现错误：条件不能为空");
        }
        if (StringUtils.isBlank(data.getDes())) {
            throw new BusinessException("在第" + rowIndex + "行发现错误：描述不能为空");
        }
        if (StringUtils.isBlank(data.getName())) {
            throw new BusinessException("在第" + rowIndex + "行发现错误：名称不能为空");
        }
        if (data.getPrice() == null) {
            throw new BusinessException("在第" + rowIndex + "行发现错误：价格不能为空");
        }
        if (data.getStock() == null) {
            throw new BusinessException("在第" + rowIndex + "行发现错误：库存不能为空");
        }
    }

    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        ReadListener.super.extra(extra, context);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("读取商品列表数据结束！");
    }

    @Override
    public boolean hasNext(AnalysisContext context) {
        return ReadListener.super.hasNext(context);
    }
}
